#include "TBuscador.h"

/***** Funciones Auxiliares *********/

int armarListaTerminos(TTokenizer* tt, char* frase, TListaSimpleOrdenada* listaTerminos);
int comparadorString(void* elem1, void* elem2);
int comparadorOrderInsercion(void* elem1, void* elem2);

/* Determina si 2 diccionarios son iguales, lo son si tienen igual usuario y fecha */
int diccionariosIguales(TDiccionario* diccionario1, TDiccionario* diccionario2){
    /* Datos del diccionario 1 */
    char usuario1[MAX_DATO];
    char fecha1[MAX_DATO];
    /* Datos del diccionario 2 */
    char usuario2[MAX_DATO];
    char fecha2[MAX_DATO];
    /* Obtiene los datos del diccionario 1 */
    TDiccionario_obtener(diccionario1, CLAVE_USUARIO_TWEET, usuario1);
    TDiccionario_obtener(diccionario1, CLAVE_FECHA_TWEET, fecha1);
    /* Obtiene los datos el diccionario 2 */
    TDiccionario_obtener(diccionario2, CLAVE_USUARIO_TWEET, usuario2);
    TDiccionario_obtener(diccionario2, CLAVE_FECHA_TWEET, fecha2);
    /* Si el usuario y la fecha son iguales los diccionarios son iguales sino no */
    if ( strcmp(usuario1, usuario2)==0 && strcmp(fecha1, fecha2)==0 ){
        return IGUAL;
    }else{
        return DISTINTO;
    }
}

int armarListasDocumentos(TBuscador* buscador, char* frase, TListaSimpleOrdenada* listasDocumentos){
    TListaSimpleOrdenada listaTerminos;
    char termino[MAX_DATO];
    TListaSimpleOrdenada listaDocumentos;
    lso_Crear(&listaTerminos, sizeof(char)*MAX_DATO, &comparadorTCampo);
    armarListaTerminos(buscador->tokenizer, frase, &listaTerminos);
    if ( !lso_Vacia(listaTerminos) ){
        /* Resultado del movimiento en la lista de terminos */
        int resultadoMovimiento;
        /* Me posiciono en el primer termino de la lista */
        resultadoMovimiento = lso_MoverCorriente(&listaTerminos, LS_PRIMERO);
        /* Mientras no se termine la lista recorro los terminos */
        while (resultadoMovimiento==0){
            /* Se cre la lista que contendra los documentos para el termino actual */
            lso_Crear(&listaDocumentos, sizeof(TDiccionario*), &comparadorTCampo);
            /* Obtiene el termino actual */
            lso_ElemCorriente(listaTerminos, termino);
            /* Obtiene del indice los documentos para ese termino */
            TIndice_listarDocs(&buscador->indice, termino, &listaDocumentos);
            /* Inserta la lista de docs para el termino actual
               en la lista de listas de documentos */
            lso_Insertar(listasDocumentos, &listaDocumentos);
            /* Se mueve al siguiente termino */
            resultadoMovimiento = lso_MoverCorriente(&listaTerminos, LS_SIGUIENTE);
        }
    }
    return CODIGO_OK;
}

int copiarElementosListaDiccionarios(TListaSimpleOrdenada listaOrigen, TListaSimpleOrdenada* listaDestino){
    TDiccionario* pDic;
    int resultadoMovimiento;
    if ( !lso_Vacia(listaOrigen) ){
        resultadoMovimiento = lso_MoverCorriente(&listaOrigen, LS_PRIMERO);
        while(resultadoMovimiento==0){
            lso_ElemCorriente(listaOrigen, &pDic);
            lso_Insertar(listaDestino, &pDic);
            resultadoMovimiento = lso_MoverCorriente(&listaOrigen, LS_SIGUIENTE);
        }
    }
    return CODIGO_OK;
}

int borrarDiccionariosNoRepetidos(TListaSimpleOrdenada* listaDestino, TListaSimpleOrdenada listaOrigen){
    TDiccionario* pDiccionarioDestino;
    int resultadoMovimientoDestino;
    TDiccionario* pDiccionarioOrigen;
    int resultadoMovimientoOrigen;
    int encontrado;
    if ( !lso_Vacia(*listaDestino) && !lso_Vacia(listaOrigen) ){
        resultadoMovimientoDestino = lso_MoverCorriente(listaDestino, LS_PRIMERO);
        while(resultadoMovimientoDestino==0){
            lso_ElemCorriente(*listaDestino, &pDiccionarioDestino);
            resultadoMovimientoOrigen = lso_MoverCorriente(&listaOrigen, LS_PRIMERO);
            encontrado = FALSE;
            while((resultadoMovimientoOrigen==0) && (!encontrado)){
                lso_ElemCorriente(listaOrigen, &pDiccionarioOrigen);
                if ( diccionariosIguales(pDiccionarioDestino, pDiccionarioOrigen)==IGUAL ){
                    encontrado = TRUE;
                }
                resultadoMovimientoOrigen = lso_MoverCorriente(&listaOrigen, LS_SIGUIENTE);
            }
            if (encontrado){
                resultadoMovimientoDestino = lso_MoverCorriente(listaDestino, LS_SIGUIENTE);
            }else{
                lso_BorrarCorriente(listaDestino);
                resultadoMovimientoDestino = CODIGO_OK;
            }
        }
    }
    return CODIGO_OK;
}

/************************************/

int TBuscador_crear(TBuscador* tb, TTokenizer* tt){
    tb->tokenizer=tt;
    TIndice_crear(&tb->indice, tt);
    return CODIGO_OK;
}

int TBuscador_destruir(TBuscador* tb){
    TIndice_destruir(&tb->indice);
    return CODIGO_OK;
}

int TBuscador_union(TBuscador* tb, char* frase, TListaSimpleOrdenada * docs){

    /****
    TDiccionario* pDic;
    TDiccionario Dic;
    char aux[256];
    TDiccionario_Crear(&Dic);
    ****/

    TListaSimpleOrdenada listasDocumentos;
    lso_Crear(&listasDocumentos, sizeof(TListaSimpleOrdenada), &comparadorTCampo); /****/
    armarListasDocumentos(tb, frase, &listasDocumentos);
    if ( !lso_Vacia(listasDocumentos) ){
        TListaSimpleOrdenada listaDocumentos;

        /****
        lso_Crear(&listaDocumentos, sizeof(TDiccionario*), &comparadorTCampo);
        ****/

        int resultadoMovimiento = lso_MoverCorriente(&listasDocumentos, LS_PRIMERO);
        while(resultadoMovimiento==0){
            lso_ElemCorriente(listasDocumentos, &listaDocumentos);

            /**solo pa probar**
            lso_ElemCorriente(listaDocumentos,&pDic);
            memcpy(&Dic,pDic, sizeof(TDiccionario));
            TDiccionario_obtener(&Dic,"id_str",aux);
            printf("%s\n",aux);
            ****/

            copiarElementosListaDiccionarios(listaDocumentos, docs);
            resultadoMovimiento = lso_MoverCorriente(&listasDocumentos, LS_SIGUIENTE);
        }
        lso_Vaciar(&listasDocumentos);
    }
    return CODIGO_OK;
}

int TBuscador_interseccion(TBuscador* tb, char* frase, TListaSimpleOrdenada * docs){
    TListaSimpleOrdenada listasDocumentos;
    lso_Crear(&listasDocumentos, sizeof(TListaSimpleOrdenada), &comparadorTCampo); /****/
    armarListasDocumentos(tb, frase, &listasDocumentos);
    if ( !lso_Vacia(listasDocumentos) ){
        TListaSimpleOrdenada listaDocumentos;
        int resultadoMovimiento = lso_MoverCorriente(&listasDocumentos, LS_PRIMERO);
        lso_ElemCorriente(listasDocumentos, &listaDocumentos);/**esta 2 lineas estan de mas no?**//**o quizas no**/
        copiarElementosListaDiccionarios(listaDocumentos, docs);
        while(resultadoMovimiento==0){
            lso_ElemCorriente(listasDocumentos, &listaDocumentos);
            borrarDiccionariosNoRepetidos(docs, listaDocumentos);
            resultadoMovimiento = lso_MoverCorriente(&listasDocumentos, LS_SIGUIENTE);
        }
        lso_Vaciar(&listasDocumentos);
    }
    return CODIGO_OK;
}

int TBuscador_indexarDiccionarios(TBuscador* tb, TListaSimpleOrdenada* listaDiccionarios){
    /* Diccionario auxuliar para procesar la lista */
    TDiccionario diccionario;
    /*TDiccionario_Crear(&diccionario);*//*no lo destruyo pq va a quedar agregado a la lista*//**VA ESTO O ALGO PARECIDO**/
    /* Si la lista de diccionarios no esta vacia la procesa */
    if ( !lso_Vacia(*listaDiccionarios) ){
        /* Mueve el corriente al primero */
        int resultadoMovimiento = lso_MoverCorriente(listaDiccionarios, LS_PRIMERO);
        /* Mientras se haya realizado el movimiento con exito sigue procesando */
        while(resultadoMovimiento==0){
            /* Obtiene el diccionario actual */
            lso_ElemCorriente(*listaDiccionarios, &diccionario);
            /* Indexa el diccionario */
            TIndice_agregar(&tb->indice, &diccionario);/**los diccionarios en algun lado estan perdiendo el campo "text" y "fecha"(y nose si algun otro). pero cuando hago el obtener de esos campos no hay nada**/
            /* Mueve el corriente al siguiente */
            resultadoMovimiento = lso_MoverCorriente(listaDiccionarios, LS_SIGUIENTE);
        }
        /* Se vacia la lista de Diccionarios */
        lso_Vaciar(listaDiccionarios);
    }
    /* Devuelve codigo de OK */
    return CODIGO_OK;
}

int TBuscador_borrarDiccionario(TBuscador* tb, char* usuario, char* fecha){
    /* Resultado de la operacion */
    int resultado;
    /* Si la fecha viene vacia llama a borrar solo por usuario */
    if ( fecha==NULL || strcmp(STRING_VACIA, fecha)==0 ){
        resultado = TIndice_eliminarUsuario(&tb->indice, usuario);
    }
    /* Si vienen usuario y fecha llama a borrar por ambos */
    else{
        resultado = TIndice_eliminarTweet(&tb->indice, usuario, fecha);
    }
    /* Devuelve el resultado de la operacion */
    return resultado;
}

int TBuscador_optimizar(TBuscador* tb){
    /* Se optimiza el indice del buscador */
    return TIndice_optimizar(&tb->indice);
}
